#include <cstdio>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;

template <class T, int capacity = 10>
class Stack{
public:
    Stack();
    ~Stack();
    bool empty() const;
    bool full() const;
    bool push(const T &);
    void pop();
    T top();
private:
    T * _data;
    int _top;
    
};
    
template<class T, int capacity>
Stack<T,capacity>::Stack()
:_data(new T[capacity]())
,_top(-1){
    cout << "Stack()" << endl;
}

template<class T, int capacity>
Stack<T,capacity>::~Stack(){
    cout << "~Stack()" << endl;
    if(_data){
        delete [] _data;
        _data = nullptr;
    }
}

template<class T, int capacity>
bool Stack<T,capacity>::empty() const{
    return _top == -1;
}

template<class T, int capacity>
bool Stack<T,capacity>::full() const{
    return _top == capacity;
}

template<class T, int capacity>
bool Stack<T,capacity>::push(const T & val){
    if(_top >= capacity - 1){
        return false;
    }
    _data[++_top] = val;
    return true;
}

template<class T, int capacity>
void Stack<T,capacity>::pop(){
    if(_top >= 0){
        --_top;
    }
    //cout << "top = " << _top<<endl;
}
template<class T, int capacity>
T Stack<T,capacity>::top(){
    return _data[_top];
}

void test(){
    Stack<int> st1;
    st1.push(1);
    st1.push(2);
    st1.push(3);
    while(!st1.empty()){
        cout << st1.top() << " ";
        st1.pop();
    }
    cout << endl<< "=============="<< endl;
    
    Stack<string> st2;
    st2.push("hello");
    st2.push("world");
    st2.push("c++");
    while(!st2.empty()){
        cout << st2.top() << " ";
        st2.pop();
    }
    cout << endl;
}

int main()
{
    

    test ();
    return 0;
}

